<dom-module id="search-banner-plugin">
	<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
	<script>
		Gerrit.install((plugin, content) => {
			plugin.registerCustomComponent('banner', 'search-banner-module')
		})
	</script>
</dom-module>

<!-- 搜索栏 -->
<dom-module id="search-banner-module">
	<template>
		<style>
			.common-bg {
				background: rgb(59, 120, 231);
			}
			.common-input {
				width: 160px;
				height: 26px;
				outline: none;
				padding-left: 5px;
				border: 1px solid rgb(221, 221, 221);
				box-sizing: border-box;
				/*color: #fff;*/
				/*background: var(--paper-input-container-shared-input-style_-_background);*/
			}
			.submit-btn {
				width: 60px;
				height: 26px;
				border: 1px solid rgb(155, 155, 155);
				border-radius: 3px;
				background-color: #ffffff;
			}
			/* 外部容器样式 */
			.search-container {
				min-width: 1580px;
				height: 60px;
				transition: height 0.2s ease-in;
				-webkit-transition: height 0.2s ease-in; /* Safari */
				display: none;
				align-items: center;
				justify-content: space-between;
				padding: 0px 40px;
				/* border-bottom: 1px solid rgb(59, 120, 231); */
			}
			/* 显隐性 */
			.search-container.nav-show {
				display: flex;
			}
			.search-container.nav-hidden {
				display: flex;
				height: 0px;
			}
			/* 关闭按钮样式 */
			.search-container .close-btn {
				background-color: rgba(0, 0, 0, 0.25);
				width: 22px;
				height: 22px;
				border-radius: 50%;
				display: flex;
				justify-content: center;
				align-items: center;
				cursor: pointer;
				transition: background-color 0.3s;
				transform: translateX(25%);
			}
			.search-container .close-btn:hover {
				background-color: rgba(0, 0, 0, 0.65);
			}
			.search-container .close-btn .icon {
				font-size: 22px;
				color: #eee;
			}
			/* 每个输入框项样式 */
			.search-container .search-item {
				min-width: 180px;
				display: flex;
				align-items: center;
				margin-right: 40px;
			}
			.search-item .title {
				margin-right: 5px;
				color: #fff;
				font-weight: var(--font-weight-bold);
				text-align: left;
				vertical-align: middle;
			}
			.nav-head0 {
				display: none;
			}
			/*select下拉框美化样式*/
			#status {
				appearance: none;
				-moz-appearance: none;
				-webkit-appearance: none;
				font-size: 14px;
			}
		</style>
		<nav class$="search-container common-bg {{navClass}}">
			<!-- 搜索Status -->
			<div class="search-item">
				<label class="title" for="status">Status:</label>
				<select
					id="status"
					class="common-input"
					on-change="handleStatusChanged"
				>
					<template is="dom-repeat" items="{{statusList}}">
						<option
							value="{{item.value}}"
							selected="{{item.selected}}"
						>
							{{item.text}}
						</option>
					</template>
				</select>
			</div>
			<!-- 搜索After -->
			<div class="search-item">
				<label class="title" for="after">After:</label>
				<input
					id="after"
					class="common-input"
					type="date"
					value="{{after}}"
					on-change="handleAfterChanged"
				/>
			</div>
			<!-- 搜索Before -->
			<div class="search-item">
				<label class="title" for="before">Before:</label>
				<input
					id="before"
					class="common-input"
					type="date"
					value="{{before}}"
					on-change="handleBeforeChanged"
				/>
			</div>
			<!-- 搜索Owner -->
			<div class="search-item">
				<searchable-input
					id="owner"
					label="Owner"
					listener="owner-filter"
					suggestions="[[ownerSgt]]"
					placeholder="eg: fanwj@ktc.cn"
				>
				</searchable-input>
			</div>
			<!-- 搜索Projects -->
			<div class="search-item">
				<searchable-input
					id="project"
					label="Projects"
					listener="project-filter"
					suggestions="[[projectSgt]]"
					placeholder="eg: 1000_9950_First"
				>
				</searchable-input>
			</div>
			<!-- 搜索Reviewer -->
			<div class="search-item">
				<searchable-input
					id="reviewer"
					label="Reviewer"
					listener="reviewer-filter"
					suggestions="[[reviewerSgt]]"
					placeholder="eg: fanwj@ktc.cn"
				>
				</searchable-input>
			</div>
			<!-- 查询&重置 -->
			<input
				class="submit-btn"
				type="submit"
				value="Search"
				on-click="handleSearch"
			/>
			<input
				class="submit-btn"
				type="submit"
				value="Reset"
				on-click="handleReset"
				style="margin-left: 5px"
			/>
			<input
				class="submit-btn"
				type="submit"
				value="Export"
				on-click="handleExport"
				style="margin-left: 5px"
			/>
			<div class="close-btn" on-click="handleClose">
				<div class="icon">&times;</div>
			</div>
		</nav>
	</template>
	<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
	<script>
		class SearchBanner extends Polymer.Element {
			// sessionStorage的键名
			SESSION_KEY = 'search-bar-status'
			// 隐藏本插件
			STATUS_HIDDEN = 'hidden'
			// 显示本插件
			STATUS_SHOW = 'show'

			static get is() {
				return 'search-banner-module'
			}

			static get properties() {
				return {
					timer: {
						type: Number,
						value: null,
					},
					navClass: {
						type: String,
						// value: 'nav-show',
					},
					// 状态
					status: {
						type: String,
						value: 'open',
					},
					// 状态下拉列表
					statusList: {
						type: Array,
						value: [
							{ text: 'open', value: 'open', selected: '' },
							{ text: 'closed', value: 'closed', selected: '' },
							{ text: 'merged', value: 'merged', selected: '' },
							{
								text: 'abandoned',
								value: 'abandoned',
								selected: '',
							},
							{
								text: 'reviewed',
								value: 'reviewed',
								selected: '',
							},
							{
								text: 'pending',
								value: 'pending',
								selected: '',
							},
							{
								text: 'new',
								value: 'new',
								selected: '',
							},
						],
					},
					// 日期限制-开始时间
					after: {
						type: String,
						value: '',
					},
					// 日期限制-结束时间
					before: {
						type: String,
						value: '',
					},
					// 账号
					owner: {
						type: String,
						value: '',
					},
					// 项目
					projects: {
						type: String,
						value: '',
					},
					// Reviewer
					reviewer: {
						type: String,
						value: '',
					},
					href: {
						type: String,
					},
					// suggestions
					ownerSgt: {
						type: Array,
						value: [],
					},
					reviewerSgt: {
						type: Array,
						value: [],
					},
				}
			}

			constructor() {
				super()
				const self = this
				this.init()
				this.href = window.location.href
				this.timer && clearInterval(this.timer)
				this.timer = setInterval(function () {
					if (self.href !== window.location.href) {
						self.href = window.location.href
						self.init()
					}
				}, 200)
			}

			connectedCallback() {
				super.connectedCallback()
				const self = this
				const owner = this.shadowRoot.querySelector('#owner')
				const reviewer = this.shadowRoot.querySelector('#reviewer')
				const project = this.shadowRoot.querySelector('#project')
				// 搜索过滤事件
				owner.addEventListener('owner-filter', (e) => {
					self.fetchOwnerSgt(e.detail.query)
				})
				reviewer.addEventListener('reviewer-filter', (e) => {
					self.fetchReviewerSgt(e.detail.query)
				})
				project.addEventListener('project-filter', (e) => {
					self.fetchProjectSgt(e.detail.query)
				})
				// 点击另一个输入框时，控制其他下拉内容隐藏
				owner.addEventListener('search-click', (e) => {
					reviewer.hiddenSgt()
					project.hiddenSgt()
				})
				reviewer.addEventListener('search-click', (e) => {
					owner.hiddenSgt()
					project.hiddenSgt()
				})
				project.addEventListener('search-click', (e) => {
					owner.hiddenSgt()
					reviewer.hiddenSgt()
				})
			}

			disconnectedCallback() {
				super.disconnetedCallback()
			}

			// 初始化参数
			init() {
				// 解析参数/q/
				const url = decodeURI(window.location.href)
				const index = url.indexOf('/q/')
				const param_index = url.indexOf('?')
				const params = url.split('?')
				// 如果包含type=search参数
				if (params.length > 1 && params[1] === 'type=search') {
					sessionStorage.setItem(this.SESSION_KEY, this.STATUS_SHOW)
				}
				if (
					sessionStorage.getItem(this.SESSION_KEY) == this.STATUS_SHOW
				) {
					// 存储sessionStorage
					const path = `${window.location.protocol}//${window.location.host}/plugins/example-servlet/`
					const self = this
					$.ajax({
						url: path + 'validLogin/', //请求的url地址
						dataType: 'json', //返回格式为json
						async: true, //请求是否异步，默认为异步，这也是ajax重要特性
						data: {}, //参数值
						type: 'GET', //请求方式
						success: function (req) {
							//返回值是json格式因此需要加上想调取的信息的key值
							// console.log(req)
							if (req.code === 200) {
								// console.log('成功')
								if (index !== -1) {
									let args
									if (param_index != -1) {
										args = url.substring(
											index + 3,
											param_index
										)
									} else {
										args = url.substring(index + 3)
									}
									self.setParams(args)
								}
								self.showNav()
							} else if (req.code === 401) {
								sessionStorage.removeItem(self.SESSION_KEY)
								self.timer && clearInterval(self.timer)
							}
							//请求成功时处理
						},
						complete: function () {
							//请求完成的处理
							// console.log('complete')
							// console.log(self.statusList)
						},
						error: function (err) {
							console.log('error', err)
							//请求出错处理
						},
					})
				}
			}

			setParams(args) {
				// 分割参数
				let argMap = {}
				let split = args.split('+')
				for (let item of split) {
					const kv = item.split(':')
					argMap[kv[0]] = kv[1]
				}
				// 处理status
				this.set('status', argMap['status'] ? argMap['status'] : 'open')
				// 处理statusList选中状态
				for (let i = 0; i < this.statusList.length; i++) {
					let item = this.statusList[i]
					if (item.value === this.status) {
						//this.set('item.selected', item.value === this.status ? 'selected' : '');
						item.selected =
							item.value === this.status ? 'selected' : ''
						this.splice('statusList', i, 1)
						this.push('statusList', item)
						break
					}
				}
				// 处理after
				this.set('after', argMap['after'])
				// 处理before
				this.set('before', argMap['before'])
				// 处理owner
				this.setInputValue('owner', argMap['owner'])
				// this.set('owner', argMap['owner'])
				// 处理projects
				this.setInputValue('project', argMap['projects'])
				// this.set('projects', argMap['projects'])
				// 处理reviewer
				this.setInputValue('reviewer', argMap['reviewer'])
				// this.set('reviewer', argMap['reviewer'])
			}

			// status状态改变
			handleStatusChanged(e) {
				this.set('status', e.target.value)
			}

			// after状态改变
			handleAfterChanged(e) {
				this.set('after', e.target.value)
			}

			// before状态改变
			handleBeforeChanged(e) {
				this.set('before', e.target.value)
			}

			// 处理查询
			handleSearch() {
				const baseUrl = `${window.location.protocol}//${window.location.host}/q/`
				window.location.href =
					baseUrl + this.combineArgs() + '?type=search'
			}

			// 合并参数
			combineArgs() {
				let args = ''
				if (this.status) args += `status:${this.status}+`
				if (this.after) args += `after:${this.after}+`
				if (this.before) args += `before:${this.before}+`
				const owner = this.getInputValue('owner')
				const projects = this.getInputValue('project')
				const reviewer = this.getInputValue('reviewer')
				if (owner) args += `owner:${owner}+`
				if (projects) args += `projects:${projects}+`
				if (reviewer) args += `reviewer:${reviewer}+`
				return args.slice(0, -1)
			}

			// 处理重置按钮
			handleReset() {
				const baseUrl = `${window.location.protocol}//${window.location.host}/q/`
				window.location.href = baseUrl + 'status:open?type=search'
			}

			// 处理关闭按钮点击事件
			handleClose() {
				sessionStorage.setItem(this.SESSION_KEY, this.STATUS_HIDDEN)
				this.hideNav()
				if (window.location.href.indexOf('type=search') != -1) {
					history.replaceState(
						null,
						null,
						window.location.href.split('?')[0]
					)
				}
			}
			// 导航栏显示
			showNav() {
				this.set('navClass', 'nav-show')
			}
			//导航栏隐藏
			hideNav() {
				this.set('navClass', 'nav-hidden')
			}
			// 获取建议
			fetchOwnerSgt(query) {
				// this.set('owner', query)
				if (query == '') {
					this.set('ownerSgt', [])
					return
				}
				// by ajax
				const self = this
				const path = `${window.location.protocol}//${window.location.host}/plugins/example-servlet`
				$.ajax({
					url: path + '/suggest/account', //请求的url地址
					dataType: 'json', //返回格式为json
					async: true, //请求是否异步，默认为异步，这也是ajax重要特性
					data: { q: query }, //参数值
					type: 'GET', //请求方式
					success: function (res) {
						// console.log(res)
						if (res.code === 200) {
							self.set('ownerSgt', [])
							const ownerSgt = res.data.map((account) => {
								return {
									label: account.name || '',
									text: account.email
										? `owner:${account.email}`
										: `owner:"${account.username}"`,
								}
							})
							self.set('ownerSgt', ownerSgt)
						}
					},
				})
			}

			fetchReviewerSgt(query) {
				// this.set('reviewer', query)
				if (query == '') {
					this.set('reviewerSgt', [])
					return
				}
				// by ajax
				const self = this
				const path = `${window.location.protocol}//${window.location.host}/plugins/example-servlet`
				$.ajax({
					url: path + '/suggest/account', //请求的url地址
					dataType: 'json', //返回格式为json
					async: true, //请求是否异步，默认为异步，这也是ajax重要特性
					data: { q: query }, //参数值
					type: 'GET', //请求方式
					success: function (res) {
						// console.log(res)
						if (res.code === 200) {
							self.set('reviewerSgt', [])
							const reviewerSgt = res.data.map((account) => {
								return {
									label: account.name || '',
									text: account.email
										? `reviewer:${account.email}`
										: `reviewer:"${account.username}"`,
								}
							})
							self.set('reviewerSgt', reviewerSgt)
						}
					},
				})
			}

			fetchProjectSgt(query) {
				// this.set('project', query)
				if (query == '') {
					this.set('projectSgt', [])
					return
				}
				// by ajax
				const self = this
				const path = `${window.location.protocol}//${window.location.host}/plugins/example-servlet`
				$.ajax({
					url: path + '/suggest/project', //请求的url地址
					dataType: 'json', //返回格式为json
					async: true, //请求是否异步，默认为异步，这也是ajax重要特性
					data: { q: query }, //参数值
					type: 'GET', //请求方式
					success: function (res) {
						// console.log(res)
						if (res.code === 200) {
							self.set('projectSgt', [])
							const projectSgt = res.data.map((project) => {
								return {
									label: project.id,
									text: project.id,
								}
							})
							self.set('projectSgt', projectSgt)
						}
					},
				})
			}

			/*设定输入框组件的值*/
			setInputValue(predicate, value) {
				const input = this.shadowRoot.querySelector('#' + predicate)
				input.search = value
			}
			/*获取输入框组件的值*/
			getInputValue(predicate) {
				const input = this.shadowRoot.querySelector('#' + predicate)
				return input.search
			}

			// 创建Xhr对象
			createXHR() {
				var XHR = [
					//兼容不同浏览器和版本得创建函数数组
					function () {
						return new XMLHttpRequest()
					},
					function () {
						return new ActiveXObject('Msxml2.XMLHTTP')
					},
					function () {
						return new ActiveXObject('Msxml3.XMLHTTP')
					},
					function () {
						return new ActiveXObject('Microsoft.XMLHTTP')
					},
				]
				var xhr = null
				//尝试调用函数，如果成功则返回XMLHttpRequest对象，否则继续尝试
				for (var i = 0; i < XHR.length; i++) {
					try {
						xhr = XHR[i]()
					} catch (e) {
						continue //如果发生异常，则继续下一个函数调用
					}
					break //如果成功，则中止循环
				}
				return xhr //返回对象实例
			}

			// 获取列表数据
			handleExport() {
				const url = decodeURI(window.location.href)
				const index = url.indexOf('/q/')
				if (index !== -1) {
					//let args = url.substring(index + 3)
					let args = this.combineArgs()
					const path = `${window.location.protocol}//${window.location.host}/plugins/example-servlet/`
					//window.location.href = url
					// console.log(path)
					$.ajax({
						url: path + 'beforeExport/', //请求的url地址
						dataType: 'json', //返回格式为json
						async: true, //请求是否异步，默认为异步，这也是ajax重要特性
						data: { q: args }, //参数值
						type: 'GET', //请求方式
						success: function (req) {
							//返回值是json格式因此需要加上想调取的信息的key值
							// console.log(req)
							if (req.code === 200) {
								window.location.href =
									path +
									'export/' +
									'?q=' +
									encodeURIComponent(args)
							} else if (req.code === 401) {
								alert('未登录，请先登录')
							} else if (req.code === 502) {
								alert('服务端错误')
							} else if (req.code === 504) {
								alert('数据为空，导出失败')
							}
							//请求成功时处理
						},
						complete: function () {
							//请求完成的处理
							// console.log('complete')
						},
						error: function (err) {
							console.log('error', err)
							//请求出错处理
						},
					})
				} else {
					alert('当前页面不允许导出,请进入Gerrit列表')
				}
			}
		}

		customElements.define(SearchBanner.is, SearchBanner)
	</script>
</dom-module>

<!-- 可下拉输入框组件 -->
<dom-module id="searchable-input">
	<template>
		<style>
			* {
				margin: 0px;
				padding: 0px;
			}

			.container {
				/*min-width: 160px;*/
				display: flex;
				align-items: center;
			}

			.container .title {
				margin-right: 5px;
				color: #fff;
				font-weight: var(--font-weight-bold);
			}

			.container .search {
				width: 160px;
				height: 26px;
				margin: 0 auto;
				position: relative;
				border: 1px solid transparent;
			}

			.search input {
				width: 160px;
				height: 26px;
				outline: none;
				padding: 2px;
				padding-left: 5px;
				font-size: 14px;
				color: rgb(33, 33, 33);
				border: 1px solid rgb(221, 221, 221);
				/* border-radius: 4px; */
				box-sizing: border-box;
			}

			.hidden {
				display: none;
			}

			/* 下拉框样式 */
			.dropdown-content {
				margin-top: 4px;
				background: var(--dropdown-background-color);
				box-shadow: rgb(0 0 0 / 30%) 0 1px 3px;
				border-radius: var(--border-radius);
				max-height: 50vh;
				overflow: auto;
				position: fixed;
				z-index: 1000;
			}

			ul {
				list-style: none;
			}

			li {
				border-bottom: 1px solid var(--border-color);
				cursor: pointer;
				display: flex;
				justify-content: space-between;
				padding: var(--spacing-m) var(--spacing-l);
			}

			li:last-of-type {
				border: none;
			}

			li:focus {
				outline: none;
			}

			li:hover {
				background-color: var(--hover-background-color);
			}

			li.selected {
				background-color: var(--selection-background-color);
			}
		</style>
		<div class="container">
			<label class="title">{{label}}:</label>
			<div class="search">
				<input
					type="text"
					autocomplete="off"
					value="{{search}}"
					placeholder="[[placeholder]]"
					on-input="filter"
					on-focus="_onInputFocus"
					on-blur="_onInputBlur"
					on-change="_onInputChange"
					on-click="_onSearchClick"
					on-keydown="_handleKeydown"
				/>

				<div
					id="dataList"
					on-click="handleClickItem"
					class$="dropdown-content [[hiddenClass]]"
				>
					<ul>
						<template is="dom-repeat" items="[[suggestions]]">
							<li class$="[[computeIsSelected(index, cursor)]]">
								[[item.label]]
							</li>
						</template>
					</ul>
				</div>
			</div>
		</div>
	</template>
	<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
	<script>
		class SearchableInput extends Polymer.Element {
			static get is() {
				return 'searchable-input'
			}

			static get properties() {
				return {
					label: String,
					search: {
						type: String,
						value: '',
					},
					hiddenClass: String,
					placeholder: String,
					suggestions: {
						type: Array,
						value: [],
					},
					cursor: {
						type: Number, // 游标
					},
					// 监听器名称
					listener: String,
				}
			}
			_handleBlurChanged(newVal) {
				if (newVal) {
					this.hiddenSgt()
				} else {
					this.showSgt()
				}
			}
			constructor() {
				super()
				this.init()
			}
			// 初始化参数
			init() {
				this.hiddenSgt()
				this.cursor = 0 // 游标
			}
			// 处理点击输入框事件
			_onSearchClick(event) {
				this.stopBubble(event)
				const self = this
				// 事件
				this.dispatchEvent(
					new CustomEvent('search-click', { detail: { id: this.id } })
				)
				document.onclick = function () {
					self.hiddenSgt()
					document.onclick = null
				}
			}
			// 处理输入框获取焦点事件
			_onInputFocus(event) {
				if (this.search) {
					this.showSgt()
				}
			}
			_onInputBlur(event) {
				// this.hiddenSgt()
			}
			// 处理输入框内容改变事件
			_onInputChange(e) {
				this.set('search', e.target.value)
			}
			// 计算是否被选中
			computeIsSelected(index, cursor) {
				return index == cursor ? 'selected' : ''
			}
			// 选中下拉选项
			handleClickItem(event) {
				this.stopBubble(event)
				const e = event.target || event.srcElement
				this.search = e.innerText
				this.fetchSuggest(this.search)
				this.hiddenSgt()
			}
			filter(event) {
				const e = event.target || event.srcElement
				const query = e.value
				this.fetchSuggest(query)
				query != '' ? this.showSgt() : this.hiddenSgt()
			}
			// 获取建议数据
			fetchSuggest(query) {
				this.set('cursor', 0)
				// 事件
				this.dispatchEvent(
					new CustomEvent(this.listener, { detail: { query } })
				)
			}
			_handleKeydown(e) {
				switch (e.keyCode) {
					case 38: // Up
						e.preventDefault()
						this.cursorUp()
						break
					case 40: // Down
						e.preventDefault()
						this.cursorDown()
						break
					case 27: // Escape
						e.preventDefault()
						this.hiddenSgt()
						break
					case 13: // Enter
					case 9: // tab
						e.preventDefault()
						this.set('search', this.suggestions[this.cursor].label)
						this.hiddenSgt()
						break
					default:
						break
				}
			}
			// 向上
			cursorUp() {
				this.set('cursor', this.cursor == 0 ? 0 : this.cursor - 1)
			}
			// 向上
			cursorDown() {
				this.set(
					'cursor',
					this.cursor == this.suggestions.length - 1
						? this.suggestions.length - 1
						: this.cursor + 1
				)
			}
			// 显示
			showSgt() {
				this.set('hiddenClass', '')
			}
			// 隐藏
			hiddenSgt() {
				this.set('hiddenClass', 'hidden')
			}
			//阻止冒泡函数
			stopBubble(e) {
				if (e && e.stopPropagation) {
					e.stopPropagation() //w3c
				} else {
					window.event.cancelBubble = true //IE
				}
			}
		}
		customElements.define(SearchableInput.is, SearchableInput)
	</script>
</dom-module>
